﻿/*************************************************
  Copyright (C), 2014-2017, lmd Tech. Co., Ltd.
  文 件  名:	Assets\Scripts\Tools\FSM\CLState.cs
  作       者:	陈佳
  版       本:	1.0        
  完成日期:	2017/08/15      
  功能描述:	
  主要功能: 轻量级的状态类,提供包装状态,状态转换,添加
*************************************************/
using System;
using CxExtension;
using TaskFunc = System.Func<float, bool>;

namespace CxExtension
{

	public class CLState
	{
		private string m_name;                                                    //状态名
		private Action m_onEnter;                                               //进入回调
		private TaskFunc m_onUpdate;                                       //更新回调
		private ListDeleteSafe<TaskFunc> m_tasks;
		private Action m_onLeave;                                              //离开回调

		public CLState() { }
		/// <summary>
		/// 构造一个状态
		/// </summary>
		/// <param name="name">状态名称,初始化后不可改变</param>
		/// <param name="enter">进入状态回调</param>
		/// <param name="update">更新状态回调</param>
		/// <param name="leave">离开状态回调</param>
		public CLState(object name, Action enter, TaskFunc update, Action leave)
		{ 
			m_name = name.ToString();
			m_onEnter = enter;
			m_onUpdate = update;
			m_onLeave = leave;
		}

		/// <summary>
		/// 添加一个任务,每次调用Update时候调用,如果任务执行返回true,表示中执行完成,会从任务列表移除
		/// 不允许添加同一个回调函数
		/// </summary>
		/// <param name="task"></param>
		public void AddTask(TaskFunc task)
		{
			if(task == null)
			{
				Debuger.ErrFormat("task参数不能为null");
				return;
			}
			if(tasks_.Contains(task))
			{
				//Debuger.WrnFormat("重复添加任务,{0}", task);
				return;
			}
			else
			{
				tasks_.Add(task);
			}
		}
		public string Name { get { return m_name; } }
		public virtual void OnEnter()
		{
			if(m_onEnter != null)
			{
				m_onEnter();
			}
		}

		public virtual bool OnUpdate(float dt)
		{
			tasks_.ForeachAll(it =>
			{
				var result = it(dt);
				if(result)
				{
					m_tasks.Remove(it);
				}
			});
			if(m_onUpdate != null)
			{
				return m_onUpdate(dt);
			}
			return true;
		}

		public virtual void OnLeave()
		{
			tasks_.Clear();
			if(m_onLeave != null)
			{
				m_onLeave();
			}
		}

		private ListDeleteSafe<TaskFunc> tasks_
		{
			get
			{
				if(m_tasks == null)
				{
					m_tasks = new ListDeleteSafe<TaskFunc>();
				}
				return m_tasks;
			}
		}
	}
}
